package com.wifipositioner.activity;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.net.wifi.ScanResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.widget.TextView;
import android.widget.Toast;

import com.wifipositioner.Globals;
import com.wifipositioner.R;
import com.wifipositioner.measure.MeasuredPoint;
import com.wifipositioner.measure.Util;
import com.wifipositioner.positioning.DistanceCalculator;
import com.wifipositioner.positioning.DistanceCalculatorUsingScanResult;
import com.wifipositioner.positioning.RefPointCache;
import com.wifipositioner.wifi.WifiProvider;

public class PositioningActivity extends Activity {
	
	private String fileNameToRead;
	private Handler wifiHandler;
	private int measureCntr = 1;
	private MeasuredPoint measuredRefPoint = new MeasuredPoint(Globals.targetRefPointName);
	private TextView tv_foundRefPont;
	private boolean isFastDevice = false;
	private List<ScanResult> lastResults = new ArrayList<ScanResult>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		setContentView(R.layout.positioning);
		tv_foundRefPont = (TextView)findViewById(R.id.positioning_et_RefPointName);
		Bundle extras = getIntent().getExtras(); 
		if(extras != null)
		{
			fileNameToRead = extras.getString(Globals.referenceFileNameExtra);
		}
		try {
			RefPointCache.get().loadCacheFromFile(fileNameToRead);
		} catch (Exception e) {
			Toast.makeText(this, "Failed to read reference map!", Toast.LENGTH_SHORT);
			e.printStackTrace();
		}
		Util.printCache();
		registerHandlers();
		WifiProvider.get().scan();
	    super.onCreate(savedInstanceState);
	}
	
	private void registerHandlers(){
		wifiHandler = new Handler(new Callback() {
			
			@Override
			public boolean handleMessage(Message msg) {
				WifiProvider.get().scan();
				if(isFastDevice){
					if(measureCntr <= Globals.maxPosMeasureCntr){
						measuredRefPoint.add((List<ScanResult>) msg.obj);
						measureCntr++;
					}
					if(measureCntr == Globals.maxPosMeasureCntr + 1){
						DistanceCalculator calculator = new DistanceCalculator(measuredRefPoint);
						measuredRefPoint = new MeasuredPoint(Globals.targetRefPointName);
						measureCntr = 1;
						tv_foundRefPont.setText(calculator.getClosestRefPointName());
					}
				}
				else{
					DistanceCalculatorUsingScanResult calculatorUsingScanResult = 
						new DistanceCalculatorUsingScanResult(filterExtremes((List<ScanResult>) msg.obj));
					tv_foundRefPont.setText(calculatorUsingScanResult.getClosestRefPointName());
				}
				return true;
			}
		});
		WifiProvider.get().registerHandler(wifiHandler);
		
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		WifiProvider.get().unregisterReciever();
		super.onActivityResult(requestCode, resultCode, data);
	}
	@Override
	protected void onStop() {
		WifiProvider.get().removeHandler(wifiHandler);
		super.onStop();
	}
	private List<ScanResult> filterExtremes(List<ScanResult> newResults){
		if(lastResults.size() > 0){
			for(ScanResult newResult : newResults){
				for(ScanResult lastResult : lastResults){
					if(lastResult.SSID.equals(newResult.SSID)){
						if(newResult.level - lastResult.level > Globals.maxSS_Step){
							newResult.level -= Globals.maxSS_Step; 
						}
						else if(newResult.level - lastResult.level < -Globals.maxSS_Step){
							newResult.level += Globals.maxSS_Step;
						}
					}
				}
			}	
		}
		lastResults = newResults;
		return newResults;
	}
}
